package com.easy.framework.common.utils;


import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.alibaba.ttl.threadpool.TtlExecutors;
import lombok.Getter;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 使用ScheduledExecutorService替代timer   Timer不支持并发
 */
public class TimerExecutorService {


    /**
     * 核心线程数
     */
    //private final static int CORE_POOL_SIZE = (int) (Runtime.getRuntime().availableProcessors() / (1 - 0.2));

    private final static int CORE_POOL_SIZE = 5;

    @Getter
    private ScheduledExecutorService scheduledExecutorService;


    public TimerExecutorService() {
        scheduledExecutorService = new ScheduledThreadPoolExecutor(2, new ThreadFactoryBuilder().build());
    }


    /**
     * @param delayTime 延迟时间
     * @param listener  回调
     */
    public void delayTimer(int delayTime, OnRunListener listener) {
        delayTimer(delayTime, TimeUnit.MILLISECONDS, listener);
    }

    /**
     * @param delayTime 延迟时间
     * @param unit      单位
     * @param listener  回调
     */
    public void delayTimer(int delayTime, TimeUnit unit, OnRunListener listener) {
        if (null != scheduledExecutorService) {
            scheduledExecutorService.schedule(new Runnable() {
                @Override
                public void run() {
                    if (listener != null) {
                        listener.run();
                    }

                }
            }, delayTime, unit);
        }
    }


    /**
     * @param intervalTime 时间间隔
     * @param listener     回调
     */
    public void cycleTimer(int intervalTime, OnRunListener listener) {
        cycleTimer(0, intervalTime, TimeUnit.MILLISECONDS, listener);
    }

    /**
     * @param startTime    开始时间
     * @param intervalTime 时间间隔
     * @param listener     回调
     */
    public void cycleTimer(int startTime, int intervalTime, OnRunListener listener) {
        cycleTimer(startTime, intervalTime, TimeUnit.MILLISECONDS, listener);
    }

    /**
     * @param startTime    开始时间
     * @param intervalTime 时间间隔
     * @param unit         单位
     * @param listener     回调
     */
    public void cycleTimer(int startTime, int intervalTime, TimeUnit unit, OnRunListener listener) {
        if (null != scheduledExecutorService) {
            scheduledExecutorService.scheduleAtFixedRate(() -> {
                if (listener != null) {
                    listener.run();
                }

            }, startTime, intervalTime, unit);
        }
    }

    public interface OnRunListener {
        void run();
    }



    //============TTL线程池

    private static class ThreadFactoryHolder {

        /**
         * TTL线程池
         */
        private final static ExecutorService EXECUTOR = TtlExecutors.getTtlExecutorService(new ThreadPoolExecutor(CORE_POOL_SIZE, (CORE_POOL_SIZE + 2), 5,
                TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000), new CommonThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()));


        static class CommonThreadFactory implements ThreadFactory {
            private final AtomicInteger index = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "common-thread-" + index.incrementAndGet());
            }
        }
    }

    public static ExecutorService getThreadPool() {
        return ThreadFactoryHolder.EXECUTOR;
    }

    public static void doAsync(Runnable runnable) {
        CompletableFuture.runAsync(runnable, getThreadPool());
    }

}
